home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ccdl151s.zip / SOURCE / EXPR.C < prev    next >
C/C++ Source or Header  |  1997-06-10  |  81KB  |  2,319 lines

  1. /*
  2.  * 68K/386 32-bit C compiler.
  3.  *
  4.  * copyright (c) 1997, David Lindauer
  5.  * 
  6.  * This compiler is intended for educational use.  It may not be used
  7.  * for profit without the express written consent of the author.
  8.  *
  9.  * It may be freely redistributed, as long as this notice remains intact
  10.  * and either the original sources or derived sources 
  11.  * are distributed along with any executables derived from the originals.
  12.  *
  13.  * The author is not responsible for any damages that may arise from use
  14.  * of this software, either idirect or consequential.
  15.  *
  16.  * v1.35 March 1997
  17.  * David Lindauer, gclind01@starbase.spd.louisville.edu
  18.  *
  19.  * Credits to Mathew Brandt for original K&R C compiler
  20.  *
  21.  */
  22. /*
  23.  * Evaluate expressions very recursive descent.  MAke sure your STACK
  24.  * is large enough to parse the expressions you want to parse.  a 4K stack
  25.  * will handle all but the very extreme cases
  26.  */
  27. #include        <stdio.h>
  28. #include        "expr.h"
  29. #include        "c.h"
  30. #include        "errors.h"
  31. #include                "list.h"
  32.  
  33. extern int block_nesting;
  34. extern int global_flag;
  35. extern enum e_sym lastst;
  36. extern char lastid[],laststr[];
  37. extern TABLE gsyms,lsyms;
  38. extern long ival;
  39. extern long double rval;
  40. /* Default types */
  41. extern TYP stdint,stdlongdouble, stduns,stdstring;
  42. TYP             stdfloat = { bt_float, 0, UF_DEFINED | UF_USED,0, 0,-1, -1, 8, {0, 0}, 0, 0,0 };
  43. TYP             stddouble = { bt_double, 0, 0,0,0, -1, -1, 8, {0, 0}, 0, 0,0 };
  44. TYP             stdvoid = { bt_matchall, 0, 0 ,0, 0,-1, -1, 4, {0, 0}, 0, 0,0 };
  45. TYP             stdmatch = { bt_matchall, 0, UF_DEFINED | UF_USED,0, 0,-1, -1, 4, {0, 0}, &stdvoid, 0,0 };
  46. TYP             stdlong = {bt_long, 0, 0,0,0,-1, -1, 4, {0, 0}, 0, 0,0 };
  47. TYP             stdunsigned = {bt_unsigned, 0, 0,0,0,-1, -1, 4, {0, 0}, 0, 0,0 };
  48. TYP             stdchar = {bt_char, 0, 0,0,0,-1, -1, 1, {0, 0}, 0, 0,0 };
  49. TYP             stdfunc = {bt_func, 1, UF_DEFINED | UF_USED,0,0,-1, -1, 0, {0, 0}, &stdint, 0,0};
  50. extern TYP      *head;          /* shared with decl */
  51. extern TABLE    tagtable;
  52. extern char declid[100];
  53. extern int goodcode;
  54. extern int prm_cplusplus;
  55. extern int regdsize,regasize,regfsize,stackadd,stackmod;
  56.  
  57. int skm_closepa[] = { closepa, comma, semicolon, end, 0 };
  58. int skm_closebr[] = { closebr, comma, openbr, semicolon, end, 0 };
  59. static SYM *lastsym;
  60. static int globaldref = 0;
  61. static char regname[] = "processor reg" ;
  62. static char *nm = 0;
  63. static TYP *asntyp = 0;
  64. static int dumpos;
  65. static SYM undef;
  66. void exprini(void)
  67. {
  68.     globaldref = 0;
  69.     asntyp = 0;
  70.     dumpos = 0;
  71.     undef.value.i = 0;
  72.     undef.name = "UNDEFINED";
  73. }
  74. ENODE    *makenode(enum e_node nt, char *v1, char *v2)
  75. /*
  76.  *      build an expression node with a node type of nt and values
  77.  *      v1 and v2.
  78.  */
  79. {       ENODE    *ep;
  80.         ep = xalloc(sizeof(ENODE));
  81.         ep->nodetype = (char)nt;
  82.                 ep->cflags = 0;
  83.         ep->v.p[0] = v1;
  84.         ep->v.p[1] = v2;
  85.         return ep;
  86. }
  87.  
  88. TYP *deref(ENODE **node, TYP *tp)
  89. /*
  90.  *      build the proper dereference operation for a node using the
  91.  *      type pointer tp.
  92.  */
  93. {
  94.                 ENODE *onode = *node;
  95.                 switch( tp->type ) {
  96.                                 case bt_double:
  97.                         *node = makenode(en_doubleref,*node,0);
  98.                         break;
  99.                                 case bt_longdouble:
  100.                         *node = makenode(en_longdoubleref,*node,0);
  101.                         break;
  102.                                 case bt_float:
  103.                         *node = makenode(en_floatref,*node,0);
  104.                         break;
  105.                                 case bt_unsignedchar:
  106.                         *node = makenode(en_ub_ref,*node,0);
  107.                         break;
  108.                                 case bt_unsignedshort:
  109.                         *node = makenode(en_uw_ref,*node,0);
  110.                         break;
  111.                 case bt_char:
  112.                         *node = makenode(en_b_ref,*node,0);
  113.                         break;
  114.                 case bt_short:
  115.                 case bt_enum:
  116.                         *node = makenode(en_w_ref,*node,0);
  117.                         break;
  118.                 case bt_unsigned:
  119.                         *node = makenode(en_ul_ref,*node,0);
  120.                                                 break;
  121.                 case bt_long:
  122.                 case bt_matchall:
  123.                 case bt_pointer:
  124.                                 case bt_ptrfunc:
  125.                                 case bt_ref:
  126.                         *node = makenode(en_l_ref,*node,0);
  127.                         break;
  128.                 default:
  129.                         generror(ERR_DEREF,0,0);
  130.                         break;
  131.                 }
  132.                 (*node)->cflags = onode->cflags;
  133.         return tp;
  134. }
  135. ENODE *dummyvar(int size, TYP *type)
  136. {
  137.     char nm[20];
  138.     ENODE *newnode;
  139.     SYM *sp = xalloc(sizeof(SYM));
  140.     sprintf(nm,"**DUMMY%d",dumpos++);
  141.     sp->name = litlate(nm);
  142.     sp->defalt = 0;
  143.   sp->storage_class = sc_auto;
  144.   sp->tp = type;
  145.     type->uflags |= UF_USED;
  146.     sp->extflag = FALSE;
  147.     sp->absflag = FALSE;
  148.     sp->intflag = FALSE;
  149.     sp->pascaldefn = FALSE;
  150.     sp->init = 0;
  151.     sp->indecltable = 0;
  152.     sp->funcparm = 0;
  153.     sp->inreg = 0;
  154.     sp->staticlabel = FALSE;
  155.     sp->value.i = block_nesting;
  156.     insert(sp,&lsyms);
  157.     newnode = makenode(en_autocon,sp,0);
  158.     return newnode;
  159. }
  160. int isintconst(int type)
  161. {
  162.     switch (type) {
  163.         case en_icon:
  164.         case en_lcon:
  165.         case en_lucon:
  166.         case en_iucon:
  167.         case en_ccon:
  168.             return 1;
  169.     }
  170.     return 0;
  171. }
  172. TYP     *nameref(ENODE **node)
  173. /*
  174.  * get an identifier.  If it is followed by parenthesis gather the
  175.  * function parms.  If it is an undefined function declare it as external
  176.  * for now.
  177.  */
  178. {       SYM             *sp;
  179.         TYP             *tp,*tp1;
  180.                 ENODE *pnode=0,*qnode = 0;
  181.                 int fn = FALSE;
  182.                 char buf[100];
  183.                 strcpy(buf,lastid);
  184.                 getsym();
  185. /* Get function args */
  186.                 if (lastst == openpa) {
  187.                     fn = TRUE;
  188.                     getsym();
  189.                     tp1 = gatherparms(&pnode);
  190.                     sp = funcovermatch(buf,tp1);
  191.                     if (sp)
  192.                         tp1->sname = nm = sp->name;
  193.                     else
  194. #ifdef CPLUSPLUS
  195.                         if (prm_cplusplus)
  196.                             tp1->sname = nm = cppmangle(buf,tp1);
  197.                         else
  198. #endif
  199.                             tp1->sname = nm = litlate(buf);
  200.                 }
  201.                 else {
  202.                     nm = litlate(buf);
  203.                     sp = gsearch(nm);
  204.                 }
  205.         if( sp == 0 ) {
  206. /* No such identifier */
  207.                 if (fn) {
  208. /* External function, put it in the symbol table */
  209. #ifdef CPLUSPLUS
  210.                                                 if (prm_cplusplus) 
  211.                                                     gensymerror(ERR_NOFUNCMATCH,nm);
  212.                                                 else
  213. #endif
  214.                                                     gensymerror(ERR_NOPROTO,nm);
  215.                         ++global_flag;
  216.                                                 sp = xalloc(sizeof(SYM));
  217.                                 sp->name = litlate(nm);
  218.                                                 sp->tp = maketype(bt_func,0);
  219.                                                 *(sp->tp) = stdfunc;
  220.                         sp->storage_class = sc_externalfunc;
  221.                                                 sp->extflag = TRUE;
  222.                         insert(sp,&gsyms);
  223.                         --global_flag;
  224.                         *node = makenode(en_napccon,sp,0);
  225.                                                 parmlist(&pnode,tp1,0);
  226.                                                 *node = makenode(en_void,*node,pnode);
  227.                         tp = &stdint;
  228.                                                 qnode = makenode(en_icon,(char *)-4,0);
  229.                           *node = makenode(en_fcall,qnode,*node);
  230.                                                 goodcode |= GF_ASSIGN;
  231.                         }
  232.                 else    {
  233. /* External non-function.  These also get put in the symbol table so that
  234.  * we don't keep spitting errors out but also put an error out
  235.  */
  236. #ifdef CPLUSPLUS
  237.                                                 if (prm_cplusplus && asntyp && asntyp->type == bt_ptrfunc) {
  238.                                                     sp = funcovermatch(lastid,asntyp);
  239.                                                     if (sp)
  240.                                                         goto foundsp;
  241.                                                 }
  242. #endif
  243.                                                 sp = xalloc(sizeof(SYM));
  244.                                 sp->name = nm;
  245.                         sp->tp = tp = &stdmatch;
  246.                                                 sp->storage_class = sc_external;
  247.                                                 insert(sp,&lsyms);
  248.                                                 *node = makenode(en_nacon,&undef,0);
  249.                                                 gensymerror(ERR_UNDEFINED,nm);
  250.                         tp = deref(node,tp);
  251.                         }
  252.                 }
  253.         else    {
  254. /* If we get here the symbol was already in the table
  255.  */
  256. foundsp:
  257.                                 sp->tp->uflags |= UF_USED;
  258.                 if( (tp = sp->tp) == 0 ) {
  259. /* This lack of type info should never happen */
  260.                         tp = &stdmatch;
  261.                                                 *node = makenode(en_nacon,&undef,0);
  262.                                                 gensymerror(ERR_UNDEFINED,nm);
  263.                         tp = deref(node,tp);
  264.                         return tp;       /* guard against untyped entries */
  265.                         }
  266.                 switch( sp->storage_class ) {
  267.                         case sc_static:
  268.                         case sc_global:
  269.                         case sc_external:
  270.                         case sc_externalfunc:
  271.                                                 case sc_abs:
  272.                                                                 sp->extflag = TRUE;
  273.                                                                 if (fn) {
  274. /* make a function node */
  275.                                                                     if (sp->tp->type == bt_ptrfunc)
  276.                                         *node = makenode(en_nacon,sp,0);
  277.                                                                     else
  278.                                         *node = makenode(en_napccon,sp,0);
  279. isfunc:
  280.                                                                     if (sp->tp->type != bt_ptrfunc && sp->tp->type != bt_func && sp->tp->type != bt_ifunc)
  281.                                                                         generror(ERR_MISMATCH,0,0);
  282.                                                                     if (sp->tp->type == bt_ptrfunc)
  283.                                                                         tp = deref(node,tp);
  284. #ifdef CPLUSPLUS
  285.                                                                     if (prm_cplusplus && !strcmp(buf,"main"))
  286.                                                                         generror(ERR_NOMAIN,0,0);
  287. #endif
  288.                                                                     parmlist(&pnode,tp1,sp->tp);
  289.                                                                     *node = makenode(en_void,*node,pnode);
  290.                                                                     qnode = makenode(en_icon,(char *)sp->tp->btp->size,0);
  291.                                   tp = tp->btp;
  292.                                                                     if (sp->intflag)
  293.                                         *node = makenode(en_intcall,qnode,*node);
  294.                                                                     else
  295.                                                                     if (tp->type == bt_union || tp->type == bt_struct) {
  296.                                                                         if (sp->pascaldefn)
  297.                                             *node = makenode(en_pfcallb,qnode,*node);
  298.                                                                         else 
  299.                                             *node = makenode(en_fcallb,qnode,*node);
  300.                                                                         (*node)->size = tp->size;
  301.                                                                     }
  302.                                                                     else
  303.                                                                         if (sp->pascaldefn)
  304.                                               *node = makenode(en_pfcall,qnode,*node);
  305.                                                                         else
  306.                                               *node = makenode(en_fcall,qnode,*node);
  307.                                                                     if (tp)
  308.                                                                         (*node)->cflags = tp->cflags;
  309.                                                                     goodcode |= GF_ASSIGN;
  310.                                                                 }
  311.                                                                 else
  312. /* otherwise make a node for a regular variable */
  313.                                                                     if (sp->absflag)
  314.                                         *node = makenode(en_absacon,sp,0);
  315.                                                                     else
  316.                                                                         if (sp->tp->type == bt_func || sp->tp->type == bt_ifunc) {
  317.                                                                             fn = TRUE;
  318.                                             *node = makenode(en_napccon,sp,0);
  319.                                                                         }
  320.                                                                         else
  321.                                                                             if (sp->staticlabel)
  322.                                                                                 *node = makenode(en_nalabcon,(char *)sp->value.i,0);
  323.                                                                             else
  324.                                                 *node = makenode(en_nacon,sp,0);
  325.                                 break;
  326.                         case sc_const:
  327. /* constants and enums */
  328.                                 *node = makenode(en_icon,(char *)sp->value.i,0);
  329.                                                                 return &stdint;
  330.                         default:        /* auto and any errors */
  331.                                 if( sp->storage_class != sc_auto && sp->storage_class != sc_autoreg) {
  332.                                         gensymerror(ERR_ILLCLASS2,sp->name);
  333.                                                                                 tp = 0;
  334.                                                                 }
  335.                                                                 else {
  336. /* auto variables */
  337.                                                                      if (sp->storage_class == sc_auto)
  338.                                         *node = makenode(en_autocon,sp,0);
  339.                                                                     else if (sp->storage_class == sc_autoreg)
  340.                                         *node = makenode(en_autoreg,sp,0);
  341.                                                                     if (fn)
  342.                                                                         goto isfunc;
  343.                                                                 }
  344.                                 break;
  345.                         }
  346. /* dereference if it isn't an array or structure address */
  347.  
  348.                                 (*node)->cflags = tp->cflags;
  349.                                 /* deref if not an array or if is function parm */
  350.                   if(!fn && tp && (tp->val_flag == 0 || (sp->funcparm && tp->type == bt_pointer)))
  351.                            tp = deref(node,tp);
  352. /* and dereference again if it is a refernece variable */
  353.                                 if (tp->type == bt_ref) {
  354.                                                 tp = tp->btp;
  355.                                                 tp = deref(node,tp);
  356.                                 }
  357.                                                 
  358.                 }
  359.                 lastsym = sp;
  360.         return tp;
  361. }
  362.  
  363. void promote_type(TYP *typ, ENODE **node)
  364. /*
  365.  * Type promotion for casts and function args 
  366.  */
  367. {
  368.         switch (typ->type) {
  369.             case bt_char:
  370.                     *node = makenode(en_cb,*node,0);
  371.                             break;
  372.             case bt_unsignedchar:
  373.                     *node = makenode(en_cub,*node,0);
  374.                     break;
  375.             case bt_enum:
  376.             case bt_short:
  377.                   *node = makenode(en_cw,*node,0);
  378.                   break;
  379.             case bt_unsignedshort:
  380.                   *node = makenode(en_cuw,*node,0);
  381.                     break;
  382.           case bt_long:
  383.                 *node = makenode(en_cl,*node,0);
  384.                     break;
  385.             case bt_unsigned:
  386.                     *node = makenode(en_cul,*node,0);
  387.                   break;
  388.             case bt_float:
  389.                   *node = makenode(en_cf,*node,0);
  390.                     break;
  391.             case bt_double:
  392.                     *node = makenode(en_cd,*node,0);
  393.                     break;
  394.             case bt_longdouble:
  395.                     *node = makenode(en_cld,*node,0);
  396.                     break;
  397.             default:
  398.                     *node = makenode(en_cp,*node,0);
  399.                     break;
  400.         }
  401.     (*node)->cflags = typ->cflags;
  402. }
  403. TYP *gatherparms( ENODE **node)
  404. /*
  405.  * create a type tree and primary parameter list for a function
  406.  *
  407.  * At this point the parameter list is backwards from what codegen
  408.  * needs!
  409.  */
  410. {
  411.     ENODE *ep1 = 0,*ep2=0,**ep3 = &ep1;
  412.     TABLE tbl;
  413.     SYM **t = &tbl.head,*newt;
  414.     TYP *tp;
  415.     int ogc = goodcode;
  416.     tbl.tail = tbl.head = 0;
  417.     goodcode |= DF_FUNCPARMS;
  418.     if (lastst == closepa) {
  419. #ifdef CPLUSPLUS
  420.         if (prm_cplusplus)
  421.             tbl.head=tbl.tail=(SYM *)-1;
  422.         else
  423. #endif
  424.             tbl.head=tbl.tail = 0;
  425.     }
  426.     else if (lastst == kw_void)
  427.         tbl.head = tbl.tail = (SYM *)-1;
  428.     else
  429.       while (lastst != closepa) {
  430.             tp = exprnc(&ep2);
  431.             if (!tp) {
  432.                 generror(ERR_EXPREXPECT,0,0);
  433.                 break;
  434.             }
  435.             ep2->cflags = tp->cflags;
  436.             newt = xalloc(sizeof(SYM));
  437.             newt->tp = tp;
  438.             newt->next = 0;
  439.             newt->name = 0;
  440.             *t = newt;
  441.             t = &newt->next;
  442.             tbl.tail = newt;
  443.             *ep3 = makenode(en_void,ep2,0);
  444.             ep3 = &(*ep3)->v.p[1];
  445.             if (lastst == comma)
  446.                 getsym();
  447.         }
  448.     needpunc(closepa,skm_closepa);
  449.     tp = maketype(bt_func,0);
  450.     tp->btp = &stdint;
  451.     tp->lst = tbl;
  452.     tp->bits = -1;
  453.     tp->startbit = -1;
  454.     tp->uflags = UF_DEFINED | UF_USED;
  455.     goodcode = ogc;
  456.     *node = ep1;
  457.     return tp;
  458. }
  459. void checkparmconst(TYP *tp, TYP *tpi)
  460. /*
  461.  * Check the CONST flags for parameters
  462.  */
  463. {
  464.     if (tpi->type != bt_pointer && tpi->type != bt_ref)
  465.         return;
  466.     while ((tp->type == bt_pointer || tp->type == bt_ref)&& !tp->val_flag && (!tpi || tpi->type == bt_pointer || tpi->type == bt_ref)) {
  467.         if ((tp->cflags & DF_CONST) && (!tpi || !(tpi->cflags & DF_CONST)))
  468.             generror(ERR_MODCONS,0,0);
  469.         tp = tp->btp;
  470.         tpi = tpi->btp;
  471.     }
  472.     if ((tp->cflags & DF_CONST) && (!tpi || !(tpi->cflags & DF_CONST)))
  473.         generror(ERR_MODCONS,0,0);
  474. }
  475. void parmlist(ENODE **node, TYP *tpi, TYP *tp)
  476. /*
  477.  * take the primary type and node trees, the function argument expectations,
  478.  * and check for type mismatch errors
  479.  *
  480.  * also reverse the primary node tree so the parms will be ready for
  481.  * code generation
  482.  */
  483. {       ENODE    *ep1=0,*ep2=0,*ep3=*node;
  484.                 SYM *spi=tpi->lst.head,*sp=0;
  485.                 TYP *tp2;
  486.                 int matching = FALSE;
  487.                 if (tp)
  488.                     sp=tp->lst.head;
  489.                 if (tp && !sp)
  490.                     gensymerror(ERR_NOPROTO,tpi->sname);
  491.                 
  492.                     if (!prm_cplusplus && sp && sp != (SYM *)-1 && sp->tp->type != bt_ellipse)
  493.                             matching = TRUE;
  494.                     while (TRUE) {
  495.                             if (!spi || spi == (SYM *)-1){
  496.                                 if (sp == (SYM *) -1)
  497.                                     break;
  498.                                 if (sp && sp->tp->type != bt_ellipse) 
  499.                                     if (!sp->defalt) 
  500.                                         genfuncerror(ERR_CALLLENSHORT,tpi->sname,0);
  501.                                     else
  502.                                         while (sp && sp != (SYM *)-1) {
  503.                                             if (sp->tp->val_flag && (sp->tp->type == bt_struct || sp->tp->type == bt_union)) {
  504.                                                 ep1 = makenode(en_stackblock,sp->defalt,ep1);
  505.                                                 sp->defalt->size = sp->tp->size;
  506.                                             }
  507.                                             else
  508.                                        ep1 = makenode(en_void,sp->defalt,ep1);
  509.                                             sp = sp->next;
  510.                                         }
  511.                                 break;
  512.                             }
  513.                             else {
  514.                             ep2 = ep3->v.p[0];
  515.                             ep3 = ep3->v.p[1];
  516.                             if (matching) {
  517.                                 if (!sp || sp == (SYM *)-1) {
  518.                                     genfuncerror(ERR_CALLLENLONG,tpi->sname,0);
  519.                                     break;
  520.                                 }
  521.                                 else {
  522.                                     checkparmconst(spi->tp,sp->tp);
  523.                                     if (!checktype(spi->tp,sp->tp))
  524.                                       if (isscalar(sp->tp) && isscalar(spi->tp))
  525.                                             promote_type(sp->tp,&ep2);
  526.                                         else
  527.                                             if (sp->tp->type == bt_pointer) {
  528.                                                 if (isintconst(ep2->nodetype)) {
  529.                                                     if (ep2->v.i != 0)
  530.                                                         generror(ERR_NONPORT,0,0);
  531.                                                 }
  532.                                                 else if (spi->tp->type != bt_pointer)
  533.                                                         genfuncerror(ERR_CALLMISMATCH,tpi->sname,sp->name);
  534.                                              }
  535.                                             else genfuncerror(ERR_CALLMISMATCH,tpi->sname,sp->name);
  536.                                 }
  537.                             }
  538.                             }
  539.                             if (sp && sp->tp->type == bt_ref) {
  540.                                 if (lvalue(ep2)) {
  541.                                     while (castvalue(ep2))
  542.                                         ep2 = ep2->v.p[0];
  543.                                     ep2 = ep2->v.p[0];
  544.                                 }
  545.                                 else {
  546.                                     ENODE *x;
  547.                                     tp2 = sp->tp->btp;
  548.                                     genfuncerror(ERR_TEMPUSED,tpi->sname,sp->name);
  549.                                     ep2 = makenode(en_refassign,dummyvar(tp2->size,tp2),ep2);
  550.                                 }
  551.                                 }
  552.                             if (spi && spi != (SYM *) -1 && spi->tp->val_flag && (spi->tp->type == bt_struct || spi->tp->type == bt_union)) {
  553.                                 ep1 = makenode(en_stackblock,ep2,ep1);
  554.                                 ep2->size = sp->tp->size;
  555.                             }
  556.                             else
  557.                        ep1 = makenode(en_void,ep2,ep1);
  558.                             spi = spi->next;
  559.                              if (sp && sp != (SYM *)-1) {
  560.                                 sp = sp->next;
  561.                                  if (sp && sp->tp->type == bt_ellipse)
  562.                                     matching = FALSE;
  563.                             }
  564.                     }
  565.                 if (tp)
  566.                     promote_type(tp->btp,&ep1);
  567.                 else
  568.                     promote_type(tpi->btp,&ep1);
  569.                 *node = ep1;
  570. }
  571.  
  572. int floatrecurse(ENODE *node)
  573. /*
  574.  * Go through a node and see if it will be promoted to type FLOAT
  575.  */
  576. {
  577.     if (!node)
  578.         return 0;
  579.     switch (node->nodetype) {
  580.                                 case en_rcon:
  581.                                 case en_lrcon:
  582.                                 case en_fcon:
  583.                                 case en_doubleref:
  584.                                 case en_longdoubleref:
  585.                                 case en_floatref:
  586.                                 case en_cld:
  587.                                 case en_cd:
  588.                                 case en_cf:
  589.                                                 return 1;
  590.                 case en_labcon: case en_trapcall: 
  591.                 case en_nacon:  case en_autocon:  case en_autoreg: case en_nalabcon:
  592.                 case en_l_ref:  case en_tempref: case en_napccon: case en_absacon:
  593.                                 case en_cl: case en_regref:
  594.                 case en_ul_ref:
  595.                                 case en_cul:
  596.                                 case en_cp:
  597.                 case en_icon:
  598.                                 case en_lcon: case en_iucon: case en_lucon: case en_ccon:
  599.                                 case en_bits:
  600.                 case en_ub_ref:
  601.                                 case en_cub:
  602.                 case en_b_ref:
  603.                                 case en_cb:
  604.                 case en_uw_ref:
  605.                                 case en_cuw:
  606.                 case en_cw:
  607.                 case en_w_ref:
  608.                 case en_eq:     case en_ne:
  609.                 case en_lt:     case en_le:
  610.                 case en_gt:     case en_ge:
  611.                                 case en_ugt: case en_uge: case en_ult: case en_ule:
  612.                         return 0;
  613.                                 case en_fcall: case en_pfcall:
  614.                                 case en_fcallb: case en_pfcallb:
  615.                                 case en_callblock:
  616.                                                 return(floatrecurse(node->v.p[1]));
  617.                 case en_not:    case en_compl:
  618.                 case en_uminus: 
  619.                 case en_ainc:   case en_adec:
  620.                                 case en_moveblock: case en_stackblock:
  621.                         return floatrecurse(node->v.p[0]);
  622.                                 case en_refassign: case en_assign:
  623.                 case en_add:    case en_sub:
  624.                                 case en_umul:        case en_udiv:    case en_umod: case en_pmul:
  625.                 case en_mul:    case en_div:
  626.                 case en_mod:    case en_and:
  627.                 case en_or:     case en_xor:
  628.                                 case en_asalsh: case en_asarsh: case en_alsh: case en_arsh:
  629.                 case en_lsh:    case en_rsh:
  630.                 case en_land:   case en_lor:
  631.                 case en_asadd:  case en_assub:
  632.                 case en_asmul:  case en_asdiv:
  633.                 case en_asmod:  case en_asand:
  634.                                 case en_asumod: case en_asudiv: case en_asumul:
  635.                 case en_asor:   case en_aslsh: case en_asxor:
  636.                 case en_asrsh:
  637.                         return(floatrecurse(node->v.p[0]) || floatrecurse(node->v.p[1]));
  638.                 case en_void:   case en_cond:
  639.                         return floatrecurse(node->v.p[1]);
  640.     }
  641.     return(0);
  642. }
  643. void floatcheck(ENODE *node)
  644. /*
  645.  * Error if node will be promoted to type float
  646.  */
  647. {
  648.     if (floatrecurse(node))
  649.         generror(ERR_INVFLOAT,0,0);
  650. }
  651. int     castbegin(int st)
  652. /*
  653.  *      return 1 if st in set of [ kw_char, kw_short, kw_long, kw_int,
  654.  *      kw_float, kw_double, kw_struct, kw_union, kw_float, or is typedef ]
  655.  */
  656. {      
  657.     SYM *sp;
  658.     switch(st) {
  659.         case kw_void:
  660.         case kw_char: case kw_short: case kw_int: case kw_long:
  661.         case kw_float: case kw_double:    
  662.         case kw_struct:    case kw_union: case kw_signed:
  663.         case kw_unsigned:    case kw_volatile:    case kw_const:
  664.             return 1;
  665.         default:
  666.             if (st != id)
  667.                 return 0;
  668.     } 
  669.     nm = lastid;
  670.     sp = gsearch(lastid);
  671.     if (!sp)
  672.         sp = search(lastid,&lsyms);
  673.     if (sp && sp->storage_class == sc_type)
  674.         return 1 ;
  675.     return 0;
  676. }
  677.  
  678. int tostring()
  679. {
  680.     short string[2048];
  681.     int st = lastst;
  682.     string[0] = 0;
  683.     while (lastst == st) {
  684.         if (st == lsconst) {
  685.             if (pstrlen(string) +pstrlen(laststr) > 2040)
  686.                 generror(ERR_STRINGTOOBIG,0,0);
  687.             else
  688.                 pstrcat(string,laststr);
  689.         }
  690.         else {
  691.             if (strlen(string) +strlen(laststr) > 4090)
  692.                 generror(ERR_STRINGTOOBIG,0,0);
  693.             else
  694.                 strcat(string,laststr);
  695.         }
  696.         getsym();
  697.     }
  698.     return(stringlit(string,st == lsconst));
  699. }
  700. TYP     *primary(ENODE **node)
  701. /*
  702.  *      primary will parse a primary expression and set the node pointer
  703.  *      returning the type of the expression parsed. primary expressions
  704.  *      are any of:
  705.  *                      id
  706.  *                      constant
  707.  *                      string
  708.  *                      ( expression )
  709.  *                      primary++
  710.  *                      primary--
  711.  *                      primary[ expression ]
  712.  *                      primary.id
  713.  *                      primary->id
  714.  *                      primary( parameter list )
  715.  *                                            (* expression)( parameter list )
  716.  *                      (typecast)primary
  717.  *                      (typecast)(unary)
  718.  */
  719. {       ENODE    *pnode, *qnode, *rnode;
  720.         SYM             *sp=0;
  721.         TYP             *tptr,*tp1,*tp2;
  722.                 int flag = 0;
  723.                 int gcode,gdf;
  724.                 int isstring = FALSE;
  725.         switch( lastst ) {
  726. /* This trap thing should be in stmt.c */
  727.                         case kw__trap:    
  728.                                     getsym();
  729.                                     if (needpunc(openpa,0)) {
  730.                                         long num = intexpr(0);
  731.                                         if (num > 15 || num < 0)
  732.                                             generror(ERR_INVTRAP,0,0);
  733.                                         if (lastst == comma) 
  734.                                             getsym();
  735.                                         tptr = gatherparms(&pnode);
  736.                                         parmlist(&pnode,tptr,0);
  737.                                         qnode = makenode(en_icon,0,0);
  738.                                         pnode = makenode(en_void,makenode(en_icon,(char *)num,0),pnode);
  739.                                         pnode = makenode(en_trapcall,qnode,pnode);
  740.                                     }
  741.                                     goodcode |= GF_ASSIGN;
  742.                                     *node = pnode;
  743.                                     return &stdint;
  744.  
  745.                         case kw_D0:
  746.                         case kw_D1:
  747.                         case kw_D2:
  748.                         case kw_D3:
  749.                         case kw_D4:
  750.                         case kw_D5:
  751.                         case kw_D6:
  752.                         case kw_D7:
  753.                         case kw_D8:
  754.                         case kw_D9:
  755.                         case kw_DA:
  756.                         case kw_DB:
  757.                         case kw_DC:
  758.                         case kw_DD:
  759.                         case kw_DE:
  760.                         case kw_DF:
  761.                                                 tptr = xalloc(sizeof(TYP));
  762.                                                 *tptr = stduns;
  763.                                                 tptr->sname = regname;
  764.                                                 pnode = makenode(en_regref,(char *)(regdsize*256+lastst-kw_D0),0);
  765.                                                 pnode = makenode(en_ul_ref,pnode,0);
  766.                                                 *node = pnode;
  767.                                                 getsym();
  768.                                                 return tptr;
  769.                         case kw_A0:
  770.                         case kw_A1:
  771.                         case kw_A2:
  772.                         case kw_A3:
  773.                         case kw_A4:
  774.                         case kw_A5:
  775.                         case kw_A6:
  776.                         case kw_A7:
  777.                         case kw_A8:
  778.                         case kw_A9:
  779.                         case kw_AA:
  780.                         case kw_AB:
  781.                         case kw_AC:
  782.                         case kw_AD:
  783.                         case kw_AE:
  784.                         case kw_AF:
  785.                                                 tptr = xalloc(sizeof(TYP));
  786.                                                 *tptr = stduns;
  787.                                                 tptr->sname = regname;
  788.                                                 pnode = makenode(en_regref,(char *)(regasize*256+lastst-kw_D0),0);
  789.                                                 pnode = makenode(en_ul_ref,pnode,0);
  790.                                                 *node = pnode;
  791.                                                 getsym();
  792.                                                 return tptr;
  793.                         case kw_F0:
  794.                         case kw_F1:
  795.                         case kw_F2:
  796.                         case kw_F3:
  797.                         case kw_F4:
  798.                         case kw_F5:
  799.                         case kw_F6:
  800.                         case kw_F7:
  801.                         case kw_F8:
  802.                         case kw_F9:
  803.                         case kw_FA:
  804.                         case kw_FB:
  805.                         case kw_FC:
  806.                         case kw_FD:
  807.                         case kw_FE:
  808.                         case kw_FF:
  809.                                                 tptr = xalloc(sizeof(TYP));
  810.                                                 *tptr = stdlongdouble;
  811.                                                 tptr->sname = regname;
  812.                                                 pnode = makenode(en_regref,(char *)(regfsize *256+lastst-kw_D0),0);
  813.                                                 pnode = makenode(en_longdoubleref,pnode,0);
  814.                                                 *node = pnode;
  815.                                                 getsym();
  816.                                                 return tptr;
  817.             case id:  
  818.                         tptr = nameref(&pnode);
  819.                         break;
  820.                 case iconst:
  821.                         tptr = &stdint;
  822.                         pnode = makenode(en_icon,(char *)ival,0);
  823.                         getsym();
  824.                                                 *node = pnode;
  825.                                                 return tptr;
  826.                 case iuconst:
  827.                         tptr = &stduns;
  828.                         pnode = makenode(en_iucon,(char *)ival,0);
  829.                         getsym();
  830.                                                 *node = pnode;
  831.                                                 return tptr;
  832.                 case lconst:
  833.                         tptr = &stdlong;
  834.                         pnode = makenode(en_lcon,(char *)ival,0);
  835.                         getsym();
  836.                                                 *node = pnode;
  837.                                                 return tptr;
  838.                 case luconst:
  839.                         tptr = &stdunsigned;
  840.                         pnode = makenode(en_lucon,(char *)ival,0);
  841.                         getsym();
  842.                                                 *node = pnode;
  843.                                                 return tptr;
  844.                 case cconst:
  845.                         tptr = &stdchar;
  846.                         pnode = makenode(en_ccon,(char *)ival,0);
  847.                         getsym();
  848.                                                 *node = pnode;
  849.                                                 return tptr;
  850.                                 case rconst:
  851.                                                 tptr = &stddouble;
  852.                                         pnode = xalloc(sizeof(ENODE));
  853.                                         pnode->nodetype = en_rcon;
  854.                                                 pnode->cflags = 0;
  855.                                                 pnode->v.f = rval;
  856.                                                 getsym();
  857.                                                 *node = pnode;
  858.                                                 return tptr;
  859.                                 case lrconst:
  860.                                                 tptr = &stdlongdouble;
  861.                                         pnode = xalloc(sizeof(ENODE));
  862.                                         pnode->nodetype = en_lrcon;
  863.                                                 pnode->cflags = 0;
  864.                                                 pnode->v.f = rval;
  865.                                                 getsym();
  866.                                                 *node = pnode;
  867.                                                 return tptr;
  868.                                 case fconst:
  869.                                                 tptr = &stdfloat;
  870.                                         pnode = xalloc(sizeof(ENODE));
  871.                                         pnode->nodetype = en_fcon;
  872.                                                 pnode->cflags = 0;
  873.                                                 pnode->v.f = rval;
  874.                                                 getsym();
  875.                                                 *node = pnode;
  876.                                                 return tptr;
  877.                 case sconst:
  878.                                                 isstring = TRUE;
  879.                         tptr = &stdstring;
  880.                         pnode = makenode(en_labcon,(char *)tostring(),0);
  881.                                                 *node = pnode;
  882.                                                 break;
  883.                 case lsconst:
  884.                                                 isstring = TRUE;
  885.                         tptr = &stdstring;
  886.                         pnode = makenode(en_labcon,(char *)tostring(),0);
  887.                                                 *node = pnode;
  888.                                                 break;
  889.                 case openpa:
  890.                         getsym();
  891.                                                 if (lastst == star) {
  892. /* function pointers */
  893.                                                                 gcode = goodcode;
  894.                                                                 goodcode &= ~(GF_AND | GF_SUPERAND);
  895.                                 getsym();
  896.                                                                 gdf = globaldref;
  897.                                                                 globaldref = 1;
  898.                                                                 tptr = expression(&pnode);
  899.                                                                 globaldref = gdf;
  900.                                                                 if (needpunc(closepa, skm_closepa)) {
  901.                                                                     if (tptr->type == bt_ptrfunc) {
  902.                                                                         tptr = deref(&pnode,tptr);
  903.                                                                         goodcode = gcode;
  904.                                                                         if (needpunc(openpa,skm_closepa)) {
  905.                                                                             goodcode |= GF_ASSIGN;
  906.                                                                             tp1 = gatherparms(&qnode);
  907.                                                                             tp1->sname = tptr->sname;
  908.                                                                             parmlist(&qnode,tp1,tptr);
  909.                                                                             rnode = makenode(en_icon,(char *)tptr->btp->size,0);
  910.                                                                             pnode = makenode(en_void,pnode,qnode);
  911.                                                                             if (tptr->cflags & DF_INT)
  912.                                                   pnode = makenode(en_intcall,rnode,pnode);
  913.                                                                             else
  914.                                                                                 if (tptr->type == bt_union || tptr->type == bt_struct) {
  915.                                                                                     if (lastsym && lastsym->pascaldefn)
  916.                                                           pnode = makenode(en_pfcallb,rnode,pnode);
  917.                                                                                     else
  918.                                                           pnode = makenode(en_fcallb,rnode,pnode);
  919.                                                                                     pnode->size = tptr->size;
  920.                                                                                 }
  921.                                                                                 else
  922.                                                                                     if (lastsym && lastsym->pascaldefn)
  923.                                                           pnode = makenode(en_pfcall,rnode,pnode);
  924.                                                                                     else
  925.                                                           pnode = makenode(en_fcall,rnode,pnode);
  926.                                                                             pnode->cflags = tptr->btp->cflags;
  927.                                                                             tptr = tptr->btp;
  928.                                                                             break;
  929.                                                                         }
  930.                                                                     }
  931.                                                                     else {
  932.                                                                         goodcode = gcode | (goodcode & GF_ASSIGN);
  933.                                                    break;
  934.                                                                      }
  935.                                                                 }
  936.                                                                 else
  937.                                                                     goodcode = gcode | GF_ASSIGN;
  938.                                                                 *node = pnode;
  939.                                                                 return tptr;
  940.                                                 }
  941.                                                 else
  942. castcont:
  943.                           if( !castbegin(lastst) ) {
  944. /* an expression in parenthesis */
  945.                                                                 gcode = goodcode;
  946.                                                                 goodcode &= ~(GF_AND | GF_SUPERAND);
  947.                                                                 gdf = globaldref;
  948.                                                                 globaldref = 0;
  949.                                                                 tptr = expression(&pnode);
  950.                                                                 globaldref = gdf;
  951.                                                                 goodcode = gcode | (goodcode & GF_ASSIGN);
  952.                                 needpuncexp(closepa,skm_closepa);
  953.                                                                 goto contfor;
  954.                                 }
  955.                           else    {       /* cast operator */
  956. /* a cast */
  957.                                                                 declid[0] = 0;
  958.                                 decl(0); /* do cast declaration */
  959.                                 decl1();
  960.                                 tptr = head;
  961.                                 if (needpunc(closepa, 0)) {
  962.                                                                     gcode = goodcode;
  963.                                                                     goodcode &= ~(GF_AND | GF_SUPERAND);
  964.                                                                     gdf = globaldref;
  965.                                                                     globaldref = 0;
  966.                                     if( (unary(&pnode)) == 0 ) {
  967.                                         generror(ERR_IDEXPECT,0,0);
  968.                                         tptr = 0;
  969.                                     }
  970.                                                                     globaldref = gdf;
  971.                                                                     goodcode = gcode | (goodcode & GF_ASSIGN);
  972.                                                                     pnode->cflags = tptr->cflags;
  973.                                                                     if (tptr) {
  974.                                                                         promote_type(tptr, &pnode);
  975.                                                                     }
  976.                                                                 }
  977.                                                                 else
  978.                                                                     return(0);
  979.                                                     }
  980.                                                 *node = pnode;
  981.                                                 return tptr;
  982.                 default:
  983.                         return 0;
  984.                 }
  985. contfor:
  986. /* modifiers that can appear after an expression */
  987.         for(;;) {
  988.                                 int i;
  989.                 switch( lastst ) {
  990.                         case autoinc:
  991.                                                 case autodec:
  992.                                                                 if (isstring)
  993.                                                                     generror(ERR_INVALIDSTRING,0,0);
  994.                                 if( tptr->type == bt_pointer )
  995.                                         i = tptr->btp->size;
  996.                                 else
  997.                                         i = 1;
  998.                                                                 if (i == 0)
  999.                                                                     generror(ERR_ZEROPTR,0,0);
  1000.                                 if(! lvalue(pnode) ) 
  1001.                                   generror(ERR_LVALUE,0,0);
  1002.                                                                 if (pnode->cflags & DF_CONST)
  1003.                                                                     generror(ERR_MODCONS,0,0);
  1004.                             
  1005.                                 pnode = makenode(lastst==autoinc ? en_ainc : en_adec,pnode,(char *)i);
  1006.                                                                 goodcode |= GF_ASSIGN;
  1007.                                 getsym();
  1008.                                                                 break;
  1009.                         case openbr:    /* build a subscript reference */
  1010.                                                                 flag = 1;
  1011.                                 if( tptr->type != bt_pointer )
  1012.                                         generrorexp(ERR_NOPOINTER,0,skm_closebr);
  1013.                                 else
  1014.                                         tptr = tptr->btp;
  1015.                                 getsym();
  1016.                                 qnode = makenode(en_icon,(char *)tptr->size,0);
  1017.                                                                 gcode = goodcode;
  1018.                                                                 goodcode &= ~(GF_AND | GF_SUPERAND);
  1019.                                                                 gdf = globaldref;
  1020.                                                                 globaldref = 0;
  1021.                                                                 tp2 = expression(&rnode);
  1022.                                                                 globaldref = gdf;
  1023.                                                                 goodcode = gcode & ~GF_ASSIGN;
  1024.                                                                 if (!isscalar(tp2) || tp2->type == bt_float || tp2->type == bt_double || tp2->type == bt_longdouble)
  1025.                                   generror(ERR_ARRAYMISMATCH,0,0);
  1026.                                 qnode = makenode(en_pmul,qnode,rnode);
  1027.                                 pnode = makenode(en_add,pnode,qnode);
  1028.                                                                 pnode->cflags = tptr->cflags;
  1029.                                 if( tptr->val_flag == 0 )
  1030.                                         tptr = deref(&pnode,tptr);
  1031.                                 needpuncexp(closebr,skm_closebr);
  1032.                                     break;
  1033.                         case pointsto: /* pointer reference */
  1034.                                 if( tptr->type != bt_pointer ) {
  1035.                                         generror(ERR_NOPOINTER,0,0);
  1036.                                                                                 while (lastst == pointsto || lastst == dot) {
  1037.                                                                                     getsym();
  1038.                                                                                     getsym();
  1039.                                                                                 }
  1040.                                                                                 break;
  1041.                                                                 }
  1042.                                 else
  1043.                                         tptr = tptr->btp;
  1044.                                                                 pnode->cflags = tptr->cflags;
  1045.                                 if( tptr->val_flag == 0 ) {
  1046.                                         pnode = makenode(en_l_ref,pnode,0);
  1047.                                                                                 pnode->cflags = tptr->cflags;
  1048.                                                                 }
  1049.                                                                 
  1050. /*
  1051.  *      fall through to dot operation
  1052.  */
  1053.                         case dot:
  1054.                                                                 if (isstring)
  1055.                                                                     generror(ERR_INVALIDSTRING,0,0);
  1056.                                 getsym();       /* past -> or . */
  1057.                                 if( lastst != id )
  1058.                                         generror(ERR_IDEXPECT,0,0);
  1059.                                 else    {
  1060.                                         sp = search(nm=litlate(lastid),&tptr->lst);
  1061.                                         if( sp == 0 ) {
  1062.                                                                         tptr = &stdmatch;
  1063.                                                                                                 pnode = makenode(en_nacon,&undef,0);
  1064.                                                 gensymerror(ERR_UNDEFINED,nm);
  1065.                                                                                                 getsym();
  1066.                                                                                                 while (lastst == pointsto || lastst == dot) {
  1067.                                                                                                     getsym();
  1068.                                                                                                     getsym();
  1069.                                                                                                 }
  1070.                                                                                 }
  1071.                                         else    {
  1072.                                                                                                     
  1073.                                                 tp2 = sp->tp;
  1074.                                                                                                 if (pnode->nodetype == en_fcallb || pnode->nodetype == en_pfcallb) {
  1075.                                                                                                     if (pnode->nodetype == en_pfcallb) 
  1076.                                                                                                         pnode = makenode(en_pcallblock,dummyvar(pnode->size,tp2),pnode);
  1077.                                                                                                     else
  1078.                                                                                                         pnode = makenode(en_callblock,dummyvar(pnode->size,tp2),pnode);
  1079.                                                                                                             
  1080.                                                                                                 }
  1081.                                                 qnode = makenode(en_icon,(char *)sp->value.i,0);
  1082.                                                 pnode = makenode(en_add,pnode,qnode);
  1083.                                                                                                 pnode->cflags = tptr->cflags | pnode->v.p[0]->cflags;
  1084.                                                                                                 tp2->uflags |= tptr->uflags;
  1085.                                                                                                 tptr = tp2; 
  1086.                                                 if( tptr->val_flag == 0 )
  1087.                                                     tptr = deref(&pnode,tptr);
  1088.                                                                                                 if (tp2->bits != -1) {
  1089.                                                                                                     qnode = pnode;
  1090.                                                                                                     pnode = makenode(en_bits,qnode,0);
  1091.                                                                                                     pnode->bits = tp2->bits;
  1092.                                                                                                     pnode->startbit = tp2->startbit;
  1093.                                                                                                     pnode->cflags = tptr->cflags | pnode->v.p[0]->cflags;
  1094.                                                                                                 }
  1095.                                         }
  1096.                                         getsym();       /* past id */
  1097.                                 }
  1098.                                 break;
  1099.                         case openpa:    /* function reference */
  1100. /* this SHOULD have been handled in nameref rather than here.  However
  1101.  * there are some weird cases like putting function names in parenthesis
  1102.  * or in hook expressions, so this has to be here too.
  1103.  */
  1104.                                                                 flag = 1;
  1105.                                                                 if (isstring)
  1106.                                                                     generror(ERR_INVALIDSTRING,0,0);
  1107.                                 if( tptr->type != bt_func &&
  1108.                                         tptr->type != bt_ifunc && tptr->type != bt_ptrfunc) {
  1109.                                         gensymerrorexp(ERR_NOFUNC,nm);
  1110.                                                                                 expskim(skm_closepa);
  1111.                                                                 }
  1112.                                 else {
  1113. #ifdef CPLUSPLUS
  1114.                                                                                 if (prm_cplusplus && !strcmp(nm,"main"))
  1115.                                                                                     generror(ERR_NOMAIN,0,0);
  1116. #endif
  1117.                                                                                 if (!sp && tptr->sname)
  1118.                                                                                     sp=gsearch(tptr->sname);
  1119.                                                                                 if (tptr->type == bt_ptrfunc)
  1120.                                                                                     tptr = deref(&pnode,tptr);
  1121.                                                 getsym();
  1122.                                                                                 tp1 =gatherparms(&qnode);
  1123.                                                                                 parmlist(&qnode,tp1,tptr);
  1124.                                                                                 rnode = makenode(en_icon,(char *)tptr->btp->size,0);
  1125.                                                                                 pnode = makenode(en_void,pnode,qnode);
  1126.                                         tptr = tptr->btp;
  1127.                                                                                 if (sp && sp->intflag)
  1128.                                                     pnode = makenode(en_intcall,rnode,pnode);
  1129.                                                                                 else
  1130.                                                                                 if (tptr->type == bt_union || tptr->type == bt_struct) {
  1131.                                                                                     if (lastsym && lastsym->pascaldefn)
  1132.                                                           pnode = makenode(en_pfcallb,rnode,pnode);
  1133.                                                                                     else
  1134.                                                           pnode = makenode(en_fcallb,rnode,pnode);
  1135.                                                                                     pnode->size = tptr->size;
  1136.                                                                                 }
  1137.                                                                                 else
  1138.                                                                                     if (lastsym && lastsym->pascaldefn)
  1139.                                                           pnode = makenode(en_pfcall,rnode,pnode);
  1140.                                                                                     else
  1141.                                                           pnode = makenode(en_fcall,rnode,pnode);
  1142.                                                                                 if (tptr)
  1143.                                                                                     pnode->cflags = tptr->cflags;
  1144.                                                                 }
  1145.                                                                 goodcode |= GF_ASSIGN;
  1146.                                 break;
  1147.                         default:
  1148.                                 goto fini;
  1149.                         }
  1150.                 }
  1151. fini:   *node = pnode;
  1152. /* symbol level error checking */
  1153.                 if (!flag && !isstring && !(goodcode & GF_AND) && lastsym && tptr->type != bt_func && tptr->type != bt_ifunc
  1154.                             &&!tptr->val_flag && lastsym->storage_class != sc_type 
  1155.                             && lastsym->storage_class != sc_static && lastsym->storage_class != sc_global
  1156.                             && lastsym->storage_class != sc_external && lastsym->storage_class != sc_externalfunc) {
  1157.                     if (!(lastsym->tp->uflags & UF_DEFINED) && lastst != assign
  1158.                         &&lastst != asplus && lastst != asminus && lastst != astimes
  1159.                         && lastst!= asdivide && lastst != asmodop && lastst != asrshift
  1160.                         && lastst != aslshift && lastst != asor && lastst != asxor && lastst != asand) {
  1161.                             gensymerror(ERR_SYMUNDEF,lastsym->name);
  1162.                             lastsym->tp->uflags |= UF_DEFINED;
  1163.                     }
  1164.                     lastsym->tp->uflags &=  ~UF_ASSIGNED;
  1165.                 }
  1166.         return tptr;
  1167. }
  1168.  
  1169. int            castvalue(ENODE *node)
  1170. /*
  1171.  * See if this is a cast operator */
  1172. {
  1173.                 switch(node->nodetype) {
  1174.                                 case en_cb: case en_cub: case en_bits:
  1175.                                 case en_cw: case en_cuw:
  1176.                                 case en_cl: case en_cul:
  1177.                                 case en_cf: case en_cd: case en_cp: case en_cld:
  1178.                         return 1;
  1179.                 }
  1180.         return 0;
  1181. }
  1182. int     lvalue(ENODE *node)
  1183. /* See if this is an lvalue; that is has it been dereferenced?
  1184.  */
  1185. {       
  1186.                 if (!prm_cplusplus) {
  1187.                     while (castvalue(node))
  1188.                         node = node->v.p[0];
  1189.                 }
  1190.                 switch( node->nodetype ) {
  1191.                 case en_b_ref:
  1192.                 case en_w_ref:
  1193.                 case en_l_ref:
  1194.                 case en_ub_ref:
  1195.                 case en_uw_ref:
  1196.                 case en_ul_ref:
  1197.                                 case en_floatref:
  1198.                                 case en_doubleref:
  1199.                                 case en_longdoubleref:
  1200.                         return 1;
  1201.                                 case en_bits:
  1202.                         return lvalue(node->v.p[0]);
  1203.                 }
  1204.         return 0;
  1205. }
  1206.  
  1207. TYP     *unary(ENODE **node)
  1208. /*
  1209.  *      unary evaluates unary expressions and returns the type of the
  1210.  *      expression evaluated. unary expressions are any of:
  1211.  *
  1212.  *                      primary
  1213.  *                      ++unary
  1214.  *                      --unary
  1215.  *                      !unary
  1216.  *                      ~unary
  1217.  *                      &unary
  1218.  *                      -unary
  1219.  *                      *unary
  1220.  *                      sizeof(typecast)
  1221.  *
  1222.  */
  1223. {       TYP             *tp,*tp1;
  1224.         ENODE    *ep1, *ep2;
  1225.         int             flag, i,gdf;
  1226.         flag = 0;
  1227.         switch( lastst ) {
  1228.                 case autodec:
  1229.                         flag = 1;
  1230.                 /* fall through to common increment */
  1231.                 case autoinc:
  1232.                         getsym();
  1233.                                                 gdf = globaldref;
  1234.                                                 globaldref = 0;
  1235.                         tp = unary(&ep1);
  1236.                                                 globaldref = gdf;
  1237.                         if( tp == 0 ) {
  1238.                                 generror(ERR_IDEXPECT,0,0);
  1239.                                 return 0;
  1240.                                 }
  1241.                                                 goodcode |= GF_ASSIGN;
  1242.                         if( lvalue(ep1)) {
  1243.                                 if( tp->type == bt_pointer ) {
  1244.                                                                                 if (tp->btp->size == 0)
  1245.                                                                                     generror(ERR_ZEROPTR,0,0);
  1246.                                         ep2 = makenode(en_icon,(char *)tp->btp->size,0);
  1247.                                                                 }
  1248.                                 else
  1249.                                         ep2 = makenode(en_icon,(char *)1,0);
  1250.                                                                 if (ep1->cflags & DF_CONST)
  1251.                                                                     generror(ERR_MODCONS,0,0);
  1252.                                 ep1 = makenode(flag ? en_assub : en_asadd,ep1,ep2);
  1253.                                 }
  1254.                         else {
  1255.                                 generror(ERR_LVALUE,0,0);
  1256.                                                                 return(0);
  1257.                                                 }
  1258.                         break;
  1259.                 case minus:
  1260.                                 case plus: {
  1261.                                                 int stt = lastst;
  1262.                         getsym();
  1263.                                                 gdf = globaldref;
  1264.                                                 globaldref = 0;
  1265.                         tp = unary(&ep1);
  1266.                                                 globaldref = gdf;
  1267.                                                 goodcode &= ~GF_ASSIGN;
  1268.                         if( tp == 0 ) {
  1269.                                 generror(ERR_IDEXPECT,0,0);
  1270.                                 return 0;
  1271.                                 }
  1272.                                                 if (stt == minus) 
  1273.                             ep1 = makenode(en_uminus,ep1,0);
  1274.                                                 }
  1275.                         break;
  1276.                 case not:
  1277.                         getsym();
  1278.                                                 gdf = globaldref;
  1279.                                                 globaldref = 0;
  1280.                         tp = unary(&ep1);
  1281.                                                 globaldref = gdf;
  1282.                                                 goodcode &= ~GF_ASSIGN;
  1283.                         if( tp == 0 ) {
  1284.                                 generror(ERR_IDEXPECT,0,0);
  1285.                                 return 0;
  1286.                                 }
  1287.                         ep1 = makenode(en_not,ep1,0);
  1288.                         break;
  1289.                 case compl:
  1290.                         getsym();
  1291.                                                 gdf = globaldref;
  1292.                                                 globaldref = 0;
  1293.                         tp = unary(&ep1);
  1294.                                                 globaldref = gdf;
  1295.                                                 goodcode &= ~GF_ASSIGN;
  1296.                         if( tp == 0 ) {
  1297.                                 generror(ERR_IDEXPECT,0,0);
  1298.                                 return 0;
  1299.                                 }
  1300.                                                 floatcheck(ep1);
  1301.                         ep1 = makenode(en_compl,ep1,0);
  1302.                         break;
  1303.                 case star:
  1304.                         getsym();
  1305.                                                 gdf = globaldref;
  1306.                                                 globaldref = 0;
  1307.                         tp = unary(&ep1);
  1308.                                                 globaldref = gdf;
  1309.                                                 goodcode &= ~GF_ASSIGN;
  1310.                         if( tp == 0 ) {
  1311.                                 generror(ERR_IDEXPECT,0,0);
  1312.                                 return 0;
  1313.                                 }
  1314.                         if( tp->btp == 0 ) {
  1315.                                 generror(ERR_DEREF,0,0);
  1316.                                                 }
  1317.                         else
  1318.                                                         if (tp->btp->type != bt_void)
  1319.                                 tp = tp->btp;
  1320.                                                 ep1->cflags = tp->cflags;
  1321.                         if( tp->val_flag == 0 )
  1322.                                 tp = deref(&ep1,tp);
  1323.                         break;
  1324.                 case and:
  1325.                         getsym();
  1326.                                                 if (!(goodcode & GF_INFUNCPARMS))
  1327.                                                     goodcode |= GF_AND;
  1328.                                                 gdf = globaldref;
  1329.                                                 globaldref = 0;
  1330.                         tp = unary(&ep1);
  1331.                                                 globaldref = gdf;
  1332.                                                 goodcode &= ~GF_AND;
  1333.                                                 goodcode &= ~GF_ASSIGN;
  1334.                         if( tp == 0 ) {
  1335.                                 generror(ERR_IDEXPECT,0,0);
  1336.                                 return 0;
  1337.                                 }
  1338.                                                 else 
  1339.                                                     if (tp->startbit != -1) 
  1340.                                                         generror(ERR_BFADDR,0,0);
  1341.                                                     else if (tp->cflags & DF_AUTOREG)
  1342.                                                         gensymerror(ERR_NOANDREG,tp->sname);
  1343.                                                     else if (tp->type == bt_pointer && tp->val_flag && !(goodcode & GF_SUPERAND))
  1344.                                                         generror(ERR_SUPERAND,0,0);
  1345.  
  1346.                         if( lvalue(ep1)) {
  1347.                                 ep1 = ep1->v.p[0];
  1348.                                                                  if (ep1->nodetype == en_regref)
  1349.                                                                     gensymerror(ERR_NOANDREG,tp->sname);
  1350.                                                 }
  1351.                         tp1 = xalloc(sizeof(TYP));
  1352.                         tp1->size = 4;
  1353.                         tp1->type = bt_pointer;
  1354.                         tp1->btp = tp;
  1355.                         tp1->val_flag = 0;
  1356.                         tp1->lst.head = 0;
  1357.                         tp1->sname = 0;
  1358.                                                 tp = tp1;
  1359.                                                 break;
  1360.                 case kw_sizeof:
  1361.                         getsym();
  1362.                         needpunc(openpa,0);
  1363.                                                 if (castbegin(lastst)) {
  1364. sizeof_cast:
  1365.                             decl(0);
  1366.                                                     decl1();
  1367.                                                 }
  1368.                                                 else if (lastst == id) {
  1369.                                                     SYM *sp = gsearch(lastid);
  1370.                                                     if (!sp)
  1371.                                                         sp = search(lastid,&lsyms);
  1372.                                                     if (sp) {
  1373.                                                             goto sizeof_primary;
  1374.                                                     }
  1375.                                                     if ((sp = search(nm,&tagtable)) != 0) {
  1376.                                                         head = sp->tp;
  1377.                                                         getsym();
  1378.                                                     }
  1379.                                                     else {
  1380.                                                         generror(ERR_SIZE,0,0);
  1381.                                                         head = 0;
  1382.                                                     }
  1383.                                                 }
  1384.                                                 else if (lastst == kw_enum) {
  1385.                                                     getsym();
  1386.                                                     if (lastst == id) {
  1387.                                                         SYM *sp;
  1388.                                                         if ((sp = search(nm,&tagtable)) != 0) {
  1389.                                                             head = sp->tp;
  1390.                                                             getsym();
  1391.                                                         }
  1392.                                                         else goto sizeof_primary;
  1393.                                                     }
  1394.                                                 }
  1395.                                                 else  {
  1396.                                                     ENODE *node = 0;
  1397. sizeof_primary:
  1398.                                                     head = unary(&node);
  1399.                                                 }
  1400.                         if( head != 0 ) {
  1401.                                                                 if (head->size == 0)
  1402.                                                                     generror(ERR_SIZE,0,0);
  1403.                                 ep1 = makenode(en_icon,(char *)head->size,0);
  1404.                                                 }
  1405.                         else    {
  1406.                                 generror(ERR_IDEXPECT,0,0);
  1407.                                 ep1 = makenode(en_icon,(char *)0,0);
  1408.                                 }
  1409.                                                 goodcode &= ~GF_ASSIGN;
  1410.                         tp = &stdint;
  1411.                         needpunc(closepa,0);
  1412.                         break;
  1413.                 default:
  1414.                         tp = primary(&ep1);
  1415.                         break;
  1416.                 }
  1417. /* Dereference if necessary */
  1418.                 if (globaldref) {
  1419.                     globaldref = 0;
  1420.                     if (tp->type != bt_ptrfunc) {
  1421.                          if( tp == 0 ) {
  1422.                generror(ERR_IDEXPECT,0,0);
  1423.                        return 0;
  1424.                 }
  1425.                         if( tp->btp == 0 ) {
  1426.                           generror(ERR_DEREF,0,0);
  1427.                         }
  1428.                         else
  1429.                             if (tp->btp->type != bt_void)
  1430.                          tp = tp->btp;
  1431.                         ep1->cflags = tp->cflags;
  1432.                 if( tp->val_flag == 0 )
  1433.                 tp = deref(&ep1,tp);
  1434.                     }
  1435.                 }
  1436.         *node = ep1;
  1437.         return tp;
  1438. }
  1439. TYP *maxsize(TYP *tp1, TYP *tp2)
  1440. /*
  1441.  * return the type that has the maximum size
  1442.  */
  1443. {
  1444.     if (tp1->type > tp2->type)
  1445.         return tp1;
  1446.     return tp2;
  1447. }
  1448. TYP     *forcefit(ENODE **node1,TYP *tp1,ENODE **node2,TYP *tp2, int max, int allowpointers)
  1449. /*
  1450.  * compare two types and determine if they are compatible for purposes
  1451.  * of the current operation.  Return an appropriate type.  Also checks for
  1452.  * dangerous pointer conversions...
  1453.  */
  1454. {                int error = ERR_MISMATCH;
  1455.                 TYP *tp3;
  1456.            switch( tp1->type ) {
  1457.                                 case bt_void:
  1458.                                                 if (tp2->type != bt_void && tp2->type != bt_matchall)
  1459.                                                     break;
  1460.                                                 return tp1;
  1461.                 case bt_long:
  1462.                                                 if (isintconst((*node2)->nodetype)) {
  1463.                                                     if (isscalar(tp2) || (!prm_cplusplus && (tp2->type == bt_pointer || tp2 ->type == bt_ptrfunc)))
  1464.                                                         return tp2;
  1465.                                                     if (tp2->type != bt_matchall)
  1466.                                                         break;
  1467.                                                 }
  1468.                 case bt_matchall:
  1469.                         if( tp2->type == bt_matchall)
  1470.                                                     return(&stdint);
  1471.                         else if( tp2->type == bt_pointer)
  1472.                           return tp2;
  1473.                                                 else if  (allowpointers && (tp2->type == bt_pointer || tp2->type == bt_ptrfunc))
  1474.                                                     return &stdint;
  1475.                                                 else if (isscalar(tp2))
  1476.                                                     if (max)
  1477.                                                         return(maxsize(tp1,tp2));
  1478.                                                     else
  1479.                                                         return(tp1);
  1480.                         break;
  1481.                 case bt_pointer:
  1482.                                                 if (!prm_cplusplus && !max && (tp2->type == bt_short || tp2->type == bt_unsignedshort
  1483.                                                     || tp2->type == bt_char || tp2->type == bt_unsignedchar)) {
  1484.                                                         error = ERR_SHORTPOINTER;
  1485.                                                         break;
  1486.                                                 }
  1487.                         if( tp2->type == bt_pointer ||tp2->type == bt_ptrfunc) {
  1488.                                                   if  (allowpointers) {
  1489.                                                       while (tp1->type == bt_pointer && tp2->type == bt_pointer) {
  1490.                                                             tp1 = tp1->btp;
  1491.                                                             tp2 = tp2->btp;
  1492.                                                         }
  1493.                                                         if (tp1->type != tp2 ->type || tp1->size != tp2->size)
  1494.                                                             if (tp1->type != bt_void && tp2->type != bt_void)
  1495.                                                                 generror(ERR_SUSPICIOUS,0,0);
  1496.                                                       return &stdint;
  1497.                                                     }
  1498.                                                     else
  1499.                             return tp1;
  1500.                                                 }
  1501.                                                 if (!prm_cplusplus && isscalar(tp2))
  1502.                                                     if (max)
  1503.                                                         return(maxsize(tp1,tp2));
  1504.                                                     else
  1505.                                                         return(tp1);
  1506.                         break;
  1507.                                 case bt_enum:
  1508.                 case bt_unsignedshort:
  1509.                 case bt_short:
  1510.                                                 if (isintconst((*node2)->nodetype)) {
  1511.                                                     if (!max && ((*node2)->v.i < -65536L || ((*node2)->v.i > 65535L))) {
  1512.                                                         error = ERR_LOSTCONV;
  1513.                                                         break;
  1514.                                                     }
  1515.                                                     return tp1;
  1516.                                                 }
  1517.                                                 else
  1518.                                                      if (!max && (tp2->type == bt_long || tp2->type == bt_unsigned || (!prm_cplusplus && (tp2->type == bt_pointer) || tp2->type == bt_ptrfunc))) {
  1519.                                                          error = ERR_LOSTCONV;
  1520.                                                           break;
  1521.                                                     }
  1522.                                               if  (allowpointers && tp2->type == bt_pointer)
  1523.                                                     return &stdint;
  1524.                                                 else if (isscalar(tp2))
  1525.                                                     if (max)
  1526.                                                         return(maxsize(tp1,tp2));
  1527.                                                     else
  1528.                                                         return(tp1);
  1529.                                                 break;
  1530.                 case bt_char:
  1531.                 case bt_unsignedchar:
  1532.                                                 if (isintconst((*node2)->nodetype)) {
  1533.                                                     if (!max && ((*node2)->v.i < -256 || ((*node2)->v.i > 255))) {
  1534.                                                         error = ERR_LOSTCONV;
  1535.                                                         break;
  1536.                                                     }
  1537.                                                     return tp1;
  1538.                                                 }
  1539.                                                 else
  1540.                                                      if (!max && (tp2->type == bt_long || tp2->type == bt_unsigned || ( !prm_cplusplus && tp2->type == bt_pointer)
  1541.                                                              || tp2->type == bt_short || tp2->type == bt_unsignedshort)) {
  1542.                                                          error = ERR_LOSTCONV;
  1543.                                                           break;
  1544.                                                     }
  1545.                                               if  (allowpointers && (tp2->type == bt_pointer || tp2->type == bt_ptrfunc))
  1546.                                                     return &stdint;
  1547.                                                 else if (isscalar(tp2))
  1548.                                                     if (max)
  1549.                                                         return(maxsize(tp1,tp2));
  1550.                                                     else
  1551.                                                         return(tp1);
  1552.                                                 break;
  1553.                                 case bt_float:
  1554.                                 case bt_double:
  1555.                                 case bt_longdouble:
  1556.                                                 if (isscalar(tp2))
  1557.                                                     return(tp1);
  1558.                                                 break;
  1559.                 case bt_unsigned:
  1560.                                                 if (isintconst((*node1)->nodetype)) {
  1561.                                                     if (isscalar(tp2) || (!prm_cplusplus && tp2->type == bt_pointer))
  1562.                                                         return tp2;
  1563.                                                     break;
  1564.                                                 }
  1565.                         if( !prm_cplusplus && (tp2->type == bt_pointer  || tp2->type == bt_ptrfunc))
  1566.                                                   if  (allowpointers)
  1567.                                                         return &stdint;
  1568.                                                     else
  1569.                                                         return tp2;
  1570.                                               if (isscalar(tp2))
  1571.                           return tp2;
  1572.                         break;
  1573.                                 case bt_ptrfunc:
  1574.                                                 if (!prm_cplusplus && (tp2->type == bt_short || tp2->type == bt_unsignedshort
  1575.                                                     || tp2->type == bt_char || tp2->type == bt_unsignedchar)) {
  1576.                                                         error = ERR_SHORTPOINTER;
  1577.                                                         break;
  1578.                                                 }
  1579.                                                 if (tp2->type == bt_pointer)
  1580.                                                     tp3 = tp2->btp;
  1581.                                                 else
  1582.                                                     tp3 = tp2;
  1583.                                                 if (tp3->type == bt_func || tp3->type == bt_ifunc || tp3->type == bt_ptrfunc
  1584.                                                             || (!prm_cplusplus && tp2->type == bt_pointer))
  1585.                                                   if  (allowpointers)
  1586.                                                       return &stdint;
  1587.                                                     else
  1588.                             return tp1;
  1589.                                                 break;
  1590.                                 case bt_func:
  1591.                                 case bt_ifunc:
  1592.                                                 if (tp2->type == bt_func || tp2->type == bt_ifunc)
  1593.                                                     return tp1;
  1594.                                                 break;
  1595.                 }
  1596. #ifdef CPLUSPLUS
  1597.                 if (error == ERR_MISMATCH && prm_cplusplus)
  1598.                     genmismatcherror(tp2,tp1);
  1599.                 else
  1600. #endif
  1601.             generror( error,0,0 );
  1602.         return tp1;
  1603. }
  1604.  
  1605. int     isscalar(TYP *tp)
  1606. /*
  1607.  * this is misnamed... it checks for ANY basic numeric type
  1608.  */
  1609. {       return  tp->type == bt_char ||  tp->type == bt_unsignedchar ||
  1610.                 tp->type == bt_short || tp->type == bt_unsignedshort ||
  1611.                 tp->type == bt_long || tp->type == bt_unsigned || tp->type == bt_enum
  1612.                                 || tp->type == bt_float || tp->type == bt_double || tp->type == bt_longdouble;
  1613. }
  1614. void checknp(TYP *tp1,TYP*tp2,ENODE *ep1, ENODE *ep2)
  1615. /*
  1616.  * look for non-portable pointer conversions
  1617.  */
  1618. {
  1619.  
  1620. #ifdef CPLUSPLUS
  1621.     if (prm_cplusplus)
  1622.         return;
  1623. #endif
  1624.     if (tp1->type == bt_pointer || tp2->type == bt_pointer)
  1625.         if (tp1->type != tp2->type) 
  1626.             if ((!isintconst(ep1->nodetype) || ep1->v.i != 0) && (!isintconst(ep2->nodetype) || ep2->v.i != 0))
  1627.                 generror(ERR_NONPORT,0,0);
  1628. }
  1629. TYP     *multops(ENODE **node)
  1630. /*
  1631.  *      multops parses the multiply priority operators. the syntax of
  1632.  *      this group is:
  1633.  *
  1634.  *              unary
  1635.  *              multop * unary
  1636.  *              multop / unary
  1637.  *              multop % unary
  1638.  */
  1639. {       ENODE    *ep1, *ep2;
  1640.         TYP             *tp1, *tp2;
  1641.         int              oper;
  1642.         tp1 = unary(&ep1);
  1643.         if( tp1 == 0 )
  1644.                 return 0;
  1645.         while( lastst == star || lastst == divide || lastst == modop ) {
  1646.                 oper = lastst;
  1647.                 getsym();       /* move on to next unary op */
  1648.                 tp2 = unary(&ep2);
  1649.                                 goodcode &= ~GF_ASSIGN;
  1650.                 if( tp2 == 0 ) {
  1651.                         generror(ERR_IDEXPECT,0,0);
  1652.                         *node = ep1;
  1653.                         return tp1;
  1654.                         }
  1655.                 tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,FALSE);
  1656.                 switch( oper ) {
  1657.                         case star:
  1658.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1659.                                         ep1 = makenode(en_umul,ep1,ep2);
  1660.                                 else
  1661.                                         ep1 = makenode(en_mul,ep1,ep2);
  1662.                                 break;
  1663.                         case divide:
  1664.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1665.                                         ep1 = makenode(en_udiv,ep1,ep2);
  1666.                                 else
  1667.                                         ep1 = makenode(en_div,ep1,ep2);
  1668.                                 break;
  1669.                         case modop:
  1670.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1671.                                         ep1 = makenode(en_umod,ep1,ep2);
  1672.                                 else
  1673.                                         ep1 = makenode(en_mod,ep1,ep2);
  1674.                                                                 floatcheck(ep1);
  1675.                                 break;
  1676.                         }
  1677.                 }
  1678.         *node = ep1;
  1679.         return tp1;
  1680. }
  1681.  
  1682. TYP     *addops(ENODE **node)
  1683. /*
  1684.  *      addops handles the addition and subtraction operators.
  1685.  */
  1686. {       ENODE    *ep1, *ep2, *ep3;
  1687.         TYP             *tp1, *tp2;
  1688.         int             oper;
  1689.         tp1 = multops(&ep1);
  1690.         if( tp1 == 0 )
  1691.                 return 0;
  1692.         while( lastst == plus || lastst == minus ) {
  1693.                 oper = (lastst == plus);
  1694.                 getsym();
  1695.                 tp2 = multops(&ep2);
  1696.                                 goodcode &= ~GF_ASSIGN;
  1697.                 if( tp2 == 0 ) {
  1698.                         generror(ERR_IDEXPECT,0,0);
  1699.                         *node = ep1;
  1700.                         return tp1;
  1701.                         }
  1702.                 if( tp1->type == bt_pointer ) {
  1703.                                         if (tp2->type == bt_pointer) {
  1704.                             forcefit(&ep1,tp1,&ep2,tp2,TRUE,FALSE);
  1705.                             ep1 = makenode( oper ? en_add : en_sub,ep1,ep2);
  1706.                                             ep1->cflags = ep1->v.p[0]->cflags | ep2->cflags;
  1707.                                             if (tp1->btp->size == 0)
  1708.                                                 generror(ERR_ZEROPTR,0,0);
  1709.                                             else
  1710.                                                 if (tp1->btp->size > 1)
  1711.                                                     ep1 = makenode(en_pdiv,ep1,makenode(en_icon,(char *)tp1->btp->size,0));
  1712.                                             ep1->cflags = ep1->v.p[0]->cflags;
  1713.                                            tp1 = &stdint;
  1714.                                             continue;
  1715.                                         }
  1716.                                         else {
  1717.                         tp2 = forcefit(0,&stdint,&ep2,tp2,TRUE,FALSE);
  1718.                                                 if (tp1->btp->size == 0)
  1719.                                                     generror(ERR_ZEROPTR,0,0);
  1720.                         ep3 = makenode(en_icon,(char *)tp1->btp->size,0);
  1721.                         ep2 = makenode(en_pmul,ep3,ep2);
  1722.                                                 ep2->cflags = ep2->v.p[1]->cflags;
  1723.                         }
  1724.                                 }
  1725.                 else if( tp2->type == bt_pointer ) {
  1726.                         tp1 = forcefit(0,&stdint,&ep1,tp1,TRUE,FALSE);
  1727.                                                 if (tp2->btp->size == 0)
  1728.                                                     generror(ERR_ZEROPTR,0,0);
  1729.                         ep3 = makenode(en_icon,(char *)tp2->btp->size,0);
  1730.                         ep1 = makenode(en_pmul,ep3,ep1);
  1731.                                                 ep1->cflags = ep1->v.p[1]->cflags;
  1732.                         }
  1733.                 tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,FALSE);
  1734.                 ep1 = makenode( oper ? en_add : en_sub,ep1,ep2);
  1735.                                 ep1->cflags = ep1->v.p[1]->cflags | ep2->cflags;
  1736.                 }
  1737. exit:
  1738.         *node = ep1;
  1739.         return tp1;
  1740. }
  1741.  
  1742. TYP     *shiftop(ENODE **node)
  1743. /*
  1744.  *      shiftop handles the shift operators << and >>.
  1745.  */
  1746. {       ENODE    *ep1, *ep2;
  1747.         TYP             *tp1, *tp2;
  1748.         int             oper;
  1749.         tp1 = addops(&ep1);
  1750.         if( tp1 == 0)
  1751.                 return 0;
  1752.         while( lastst == lshift || lastst == rshift) {
  1753.                 oper = (lastst == lshift);
  1754.                 getsym();
  1755.                 tp2 = addops(&ep2);
  1756.                                 goodcode &= ~GF_ASSIGN;
  1757.                 if( tp2 == 0 )
  1758.                         generror(ERR_IDEXPECT,0,0);
  1759.                 else    {
  1760.                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,FALSE);
  1761.                                                 if (tp1->type == bt_unsigned ||
  1762.                                                         tp1->type == bt_unsignedchar ||
  1763.                                                         tp1->type == bt_unsignedshort)
  1764.                             ep1 = makenode(oper ? en_lsh : en_rsh,ep1,ep2);
  1765.                                                 else
  1766.                             ep1 = makenode(oper ? en_alsh : en_arsh,ep1,ep2);
  1767.                         }
  1768.                                 floatcheck(ep1);
  1769.                 }
  1770.         *node = ep1;
  1771.         return tp1;
  1772. }
  1773.  
  1774. TYP     *relation(ENODE **node)
  1775. /*
  1776.  *      relation handles the relational operators < <= > and >=.
  1777.  */
  1778. {       ENODE    *ep1, *ep2;
  1779.         TYP             *tp1, *tp2;
  1780.         int             nt;
  1781.         tp1 = shiftop(&ep1);
  1782.         if( tp1 == 0 )
  1783.                 return 0;
  1784.         for(;;) {
  1785.                 switch( lastst ) {
  1786.  
  1787.                         case lt:
  1788.                                 if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1789.                                         nt = en_ult;
  1790.                                 else
  1791.                                         nt = en_lt;
  1792.                                 break;
  1793.                         case gt:
  1794.                                 if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1795.                                         nt = en_ugt;
  1796.                                 else
  1797.                                         nt = en_gt;
  1798.                                 break;
  1799.                         case leq:
  1800.                                 if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1801.                                         nt = en_ule;
  1802.                                 else
  1803.                                         nt = en_le;
  1804.                                 break;
  1805.                         case geq:
  1806.                                 if( tp1->type == bt_unsigned || tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  1807.                                         nt = en_uge;
  1808.                                 else
  1809.                                         nt = en_ge;
  1810.                                 break;
  1811.                         default:
  1812.                                 goto fini;
  1813.                         }
  1814.                 getsym();
  1815.                 tp2 = shiftop(&ep2);
  1816.                                 goodcode &= ~GF_ASSIGN;
  1817.                 if( tp2 == 0 )
  1818.                         generror(ERR_IDEXPECT,0,0);
  1819.                 else    {
  1820.                                                 checknp(tp1,tp2,ep1,ep2);
  1821.                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,TRUE);
  1822.                         ep1 = makenode(nt,ep1,ep2);
  1823.                         }
  1824.                 }
  1825. fini:   *node = ep1;
  1826.         return tp1;
  1827. }
  1828.  
  1829. TYP     *equalops(ENODE **node)
  1830. /*
  1831.  *      equalops handles the equality and inequality operators.
  1832.  */
  1833. {       ENODE    *ep1, *ep2;
  1834.         TYP             *tp1, *tp2;
  1835.         int             oper;
  1836.         tp1 = relation(&ep1);
  1837.         if( tp1 == 0 )
  1838.                 return 0;
  1839.         while( lastst == eq || lastst == neq ) {
  1840.                 oper = (lastst == eq);
  1841.                 getsym();
  1842.                 tp2 = relation(&ep2);
  1843.                                 goodcode &= ~GF_ASSIGN;
  1844.                                 checknp(tp1,tp2,ep1,ep2);
  1845.                 if( tp2 == 0 )
  1846.                         generror(ERR_IDEXPECT,0,0);
  1847.                 else    {
  1848.                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,TRUE);
  1849.                         ep1 = makenode( oper ? en_eq : en_ne,ep1,ep2);
  1850.                         }
  1851.                 }
  1852.         *node = ep1;
  1853.         return tp1;
  1854. }
  1855.  
  1856. TYP     *binop(ENODE **node,TYP *(*xfunc)(),int nt,int sy)
  1857. /*
  1858.  *      binop is a common routine to handle all of the legwork and
  1859.  *      error checking for bitand, bitor, bitxor, andop, and orop.
  1860.  */
  1861. {       ENODE    *ep1, *ep2;
  1862.         TYP             *tp1, *tp2;
  1863.         tp1 = (*xfunc)(&ep1);
  1864.         if( tp1 == 0 )
  1865.                 return 0;
  1866.         while( lastst == sy ) {
  1867.                 getsym();
  1868.                 tp2 = (*xfunc)(&ep2);
  1869.                                 goodcode &= ~GF_ASSIGN;
  1870.                 if( tp2 == 0 )
  1871.                         generror(ERR_IDEXPECT,0,0);
  1872.                 else    {
  1873.                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,TRUE,sy == lor || sy == land);
  1874.                         ep1 = makenode(nt,ep1,ep2);
  1875.                         }
  1876.                                 floatcheck(ep1);
  1877.                 }
  1878.         *node = ep1;
  1879.         return tp1;
  1880. }
  1881.  
  1882. TYP     *bitand(ENODE **node)
  1883. /*
  1884.  *      the bitwise and operator...
  1885.  */
  1886. {       return binop(node,equalops,en_and,and);
  1887. }
  1888.  
  1889. TYP     *bitxor(ENODE **node)
  1890. {       return binop(node,bitand,en_xor,uparrow);
  1891. }
  1892.  
  1893. TYP     *bitor(ENODE **node)
  1894. {       return binop(node,bitxor,en_or,or);
  1895. }
  1896.  
  1897. TYP     *andop(ENODE **node)
  1898. {       return binop(node,bitor,en_land,land);
  1899. }
  1900.  
  1901. TYP     *orop(ENODE **node)
  1902. {       return binop(node,andop,en_lor,lor);
  1903. }
  1904.  
  1905. TYP     *conditional(ENODE **node)
  1906. /*
  1907.  *      this routine processes the hook operator.
  1908.  */
  1909. {       TYP             *tp1, *tp2, *tp3;
  1910.         ENODE    *ep1, *ep2, *ep3;
  1911.         tp1 = orop(&ep1);       /* get condition */
  1912.  
  1913.         if( tp1 == 0 )
  1914.                 return 0;
  1915.         if( lastst == hook ) {
  1916.                                 int gcode1,gcode2;
  1917.                                 goodcode &=~GF_ASSIGN;
  1918.                 getsym();
  1919.                 if( (tp2 = conditional(&ep2)) == 0) {
  1920.                         generror(ERR_IDEXPECT,0,0);
  1921.                                                 goodcode &= ~GF_ASSIGN;
  1922.                         goto cexit;
  1923.                         }
  1924.                 needpunc(colon,0);
  1925.                                 gcode2 = goodcode;
  1926.                                 goodcode &=~GF_ASSIGN;
  1927.                 if( (tp3 = conditional(&ep3)) == 0) {
  1928.                         generror(ERR_IDEXPECT,0,0);
  1929.                                                 goodcode &= ~GF_ASSIGN;
  1930.                         goto cexit;
  1931.                         }
  1932.                                 gcode1 = gcode2 & goodcode;
  1933.                                 goodcode = (goodcode &~GF_ASSIGN) | gcode1;
  1934.                 tp1 = forcefit(&ep2,tp2,&ep3,tp3,TRUE,FALSE);
  1935.                 ep2 = makenode(en_void,ep2,ep3);
  1936.                 ep1 = makenode(en_cond,ep1,ep2);
  1937.                 }
  1938. cexit:
  1939.               *node = ep1;
  1940.         return tp1;
  1941. }
  1942. TYP            *autoasnop(ENODE **node, SYM *sp)
  1943. /*
  1944.  *             Handle assignment operators during auto init of local vars
  1945.  */
  1946. {       ENODE    *ep1, *ep2;
  1947.         TYP             *tp1, *tp2;
  1948.  
  1949.         if( (tp1 = sp->tp) == 0 ) {
  1950.                     tp1 = &stdmatch;
  1951.                     *node = makenode(en_nacon,&undef,0);
  1952.                     gensymerror(ERR_UNDEFINED,nm);
  1953.           tp1 = deref(&ep1,tp1);
  1954.           return tp1;       /* guard against untyped entries */
  1955.         }
  1956.         if( sp->storage_class != sc_auto && sp->storage_class != sc_autoreg)
  1957.           gensymerror(ERR_ILLCLASS2,sp->name);
  1958.                 if (sp->storage_class == sc_auto)
  1959.             ep1 = makenode(en_autocon,sp,0);
  1960.                 else if (sp->storage_class == sc_autoreg)
  1961.             ep1 = makenode(en_autoreg,sp,0);
  1962.                 if (tp1) {
  1963.                     tp1->uflags |= UF_DEFINED | UF_USED;
  1964.                 }
  1965.                 if ((tp1->uflags & UF_CANASSIGN) && !(goodcode & GF_INLOOP))
  1966.                     tp1->uflags |=  UF_ASSIGNED;
  1967.         if( tp1->val_flag == 0)
  1968.           tp1 = deref(&ep1,tp1);
  1969.         if( tp1 == 0 )
  1970.                 return 0;
  1971.         tp2 = asnop(&ep2,tp1);
  1972.         if( tp2 == 0) {
  1973.           generror(ERR_LVALUE,0,0);
  1974.                     *node = makenode(en_nacon,&undef,0);
  1975.                 }
  1976.         else    {
  1977.                     if (tp1->type == bt_struct || tp1->type == bt_union) {
  1978.                         if (!checktypeassign(tp1,tp2)) {
  1979.                  generror(ERR_LVALUE,0,0);
  1980.                             *node = makenode(en_nacon,&undef,0);
  1981.                         }
  1982.                         else {
  1983.                             checknp(tp1,tp2,ep1,ep2);
  1984.                             if (ep2->nodetype == en_fcallb || ep2->nodetype == en_pfcallb)
  1985.                                 if (ep2->nodetype == en_pfcallb) 
  1986.                                     ep1 = makenode(en_pcallblock,ep1,ep2);
  1987.                                 else
  1988.                                     ep1 = makenode(en_callblock,ep1,ep2);
  1989.                             else
  1990.                                 ep1 = makenode(en_moveblock,ep1,ep2);
  1991.                             ep1->size = tp1->size;
  1992.                             *node = ep1;
  1993.                         }
  1994.                     }
  1995.           else    {
  1996.                         if (tp1->type == bt_ref) {
  1997.                             if (lvalue(ep2)) {
  1998.                                  while (castvalue(ep2))
  1999.                                      ep2 = ep2->v.p[0];
  2000.                                 ep2 = ep2->v.p[0];
  2001.                                 tp1 = tp1->btp;
  2002.                             }
  2003.                             else {
  2004.                                 tp1 = tp1->btp;
  2005.                                 gensymerror(ERR_TEMPINIT,sp->name);
  2006.                                 ep2 = makenode(en_refassign,dummyvar(tp1->size,tp1),ep2);
  2007.                             }
  2008.                         }
  2009.                         else if (tp1->val_flag) {
  2010.                             generror(ERR_LVALUE,0,0);
  2011.                             *node = makenode(en_nacon,&undef,0);
  2012.                             return tp1;
  2013.                         }
  2014.                         
  2015.                         checknp(tp1,tp2,ep1,ep2);
  2016.               tp1 = forcefit(&ep1,tp1,&ep2,tp2,FALSE,FALSE);
  2017.               *node = makenode(en_assign,ep1,ep2);
  2018.                     }
  2019.         }
  2020.                 return(tp1);
  2021. }
  2022. void asncombine(ENODE **node)
  2023. /*
  2024.  * a simple optimization which turns an equate into a functional equate
  2025.  * if possible.  Code gen proceeds a little more cleanly if this info
  2026.  * is known.
  2027.  */
  2028. {
  2029.     ENODE *var = (*node)->v.p[0];
  2030.     ENODE *exp = (*node)->v.p[1];
  2031.   ENODE *var2 = exp->v.p[0];
  2032.         int op = 0;
  2033.         switch(exp->nodetype) {
  2034.             case en_add:
  2035.                 if (equalnode(var,var2)) {
  2036.                     op = en_asadd;
  2037.                     break;
  2038.                 } else return;
  2039.             case en_sub:
  2040.                 if (equalnode(var,var2)) {
  2041.                     op = en_assub;
  2042.                     break;
  2043.                 } else return;
  2044.             case en_mul:
  2045.                 if (equalnode(var,var2)) {
  2046.                     op = en_asmul;
  2047.                     break;
  2048.                 } else return;
  2049.             case en_umul:
  2050.                 if (equalnode(var,var2)) {
  2051.                     op = en_asumul;
  2052.                     break;
  2053.                 } else return;
  2054.             case en_div:
  2055.                 if (equalnode(var,var2)) {
  2056.                     op = en_asdiv;
  2057.                     break;
  2058.                 } else return;
  2059.             case en_udiv:
  2060.                 if (equalnode(var,var2)) {
  2061.                     op = en_asudiv;
  2062.                     break;
  2063.                 } else return;
  2064.             case en_mod:
  2065.                 if (equalnode(var,var2)) {
  2066.                     op = en_asmod;
  2067.                     break;
  2068.                 } else return;
  2069.             case en_umod:
  2070.                 if (equalnode(var,var2)) {
  2071.                     op = en_asumod;
  2072.                     break;
  2073.                 } else return;
  2074.             case en_lsh:
  2075.                 if (equalnode(var,var2)) {
  2076.                     op = en_aslsh;
  2077.                     break;
  2078.                 } else return;
  2079.             case en_alsh:
  2080.                 if (equalnode(var,var2)) {
  2081.                     op = en_asalsh;
  2082.                     break;
  2083.                 } else return;
  2084.             case en_rsh:
  2085.                 if (equalnode(var,var2)) {
  2086.                     op = en_asrsh;
  2087.                     break;
  2088.                 } else return;
  2089.             case en_arsh:
  2090.                 if (equalnode(var,var2)) {
  2091.                     op = en_asarsh;
  2092.                     break;
  2093.                 } else return;
  2094.             case en_and:
  2095.                 if (equalnode(var,var2)) {
  2096.                     op = en_asand;
  2097.                     break;
  2098.                 } else return;
  2099.             case en_or:
  2100.                 if (equalnode(var,var2)) {
  2101.                     op = en_asor;
  2102.                     break;
  2103.                 } else return;
  2104.             case en_xor:
  2105.                 if (equalnode(var,var2)) {
  2106.                     op = en_asxor;
  2107.                     break;
  2108.                 } else return;
  2109.             default:
  2110.                     return;
  2111.         }
  2112.         exp->nodetype = op;
  2113.         (*node) = exp;
  2114. }
  2115. TYP     *asnop(ENODE **node,TYP *tptr)
  2116. /*
  2117.  *      asnop handles the assignment operators.
  2118.  */
  2119. {       ENODE    *ep1, *ep2, *ep3;
  2120.         TYP             *tp1, *tp2,*oldastyp;
  2121.         int             op;
  2122.                 oldastyp = asntyp;
  2123.                 if (tptr) 
  2124.                     asntyp = tptr;
  2125.                 else
  2126.                     asntyp = 0;
  2127.         tp1 = conditional(&ep1);
  2128.                 lastsym = 0;
  2129.                 if (!tptr)
  2130.                     asntyp = tp1;
  2131.         if( tp1 == 0 )
  2132.                 return 0;
  2133.         for(;;) {
  2134.                 switch( lastst ) {
  2135.                         case assign:
  2136.                                 op = en_assign;
  2137. ascomm:                         getsym();
  2138.                                 tp2 = asnop(&ep2,asntyp);
  2139. ascomm2:                        ep3 = ep1;
  2140.                                                                 if (tp1) {
  2141.                                                                     tp1->uflags |= UF_DEFINED;
  2142.                                                                 }
  2143.                                                                 goodcode |= GF_ASSIGN;
  2144.                                                                 if ((tp1->uflags & UF_CANASSIGN) && !(goodcode & GF_INLOOP))
  2145.                                                                     tp1->uflags |=  UF_ASSIGNED;
  2146.                                                                 if( tp2 == 0 || tp1 == 0)
  2147.                                         generror(ERR_LVALUE,0,0);
  2148.                                                                 else {
  2149.                                                                         if (tp1->type == bt_struct || tp1->type == bt_union) {
  2150.                                                                                 if (!checktypeassign(tp1,tp2)) {
  2151.                                             generror(ERR_LVALUE,0,0);
  2152.                                                                                 }
  2153.                                                                                 else {
  2154.                                                                                     if (op != en_asadd && op != en_assub)
  2155.                                                                                         checknp(tp1,tp2,ep1,ep2);
  2156.                                                                                     if (ep2->nodetype == en_fcallb || ep2->nodetype == en_pfcallb)
  2157.                                                                                         if (ep2->nodetype == en_pfcallb) 
  2158.                                                                                             ep1 = makenode(en_pcallblock,ep1,ep2);
  2159.                                                                                         else
  2160.                                                                                             ep1 = makenode(en_callblock,ep1,ep2);
  2161.                                                                                     else
  2162.                                                                                         ep1 = makenode(en_moveblock,ep1,ep2);
  2163.                                                                                     ep1->size = tp1->size;
  2164.                                                                                 }
  2165.                                                                         }
  2166.                                   else    {
  2167.                                                                                 if (!lvalue(ep1)) 
  2168.                                                                           generror(ERR_LVALUE,0,0);
  2169.                                                                                 if (op != en_asadd && op != en_assub)
  2170.                                                                                     checknp(tp1,tp2,ep1,ep2);
  2171.                                         tp1 = forcefit(&ep1,tp1,&ep2,tp2,FALSE,FALSE);
  2172.                                         ep1 = makenode(op,ep1,ep2);
  2173.                                         }
  2174.                                                                 }
  2175.                                                               if (ep3->cflags & DF_CONST)
  2176.                                                                   generror(ERR_MODCONS,0,0);
  2177.                                                               if (op == en_assign) {
  2178.                                                                   asncombine(&ep1);
  2179.                                                                     op = ep1->nodetype;
  2180.                                                                 }
  2181.                                                               if (op == en_asmod || op == en_asumod ||
  2182.                                                                               op ==en_aslsh || op== en_asrsh ||
  2183.                                                                               op == en_asalsh || op== en_asarsh ||
  2184.                                                                               op == en_asand || op== en_asor || op == en_asxor)
  2185.                                                                   floatcheck(ep1);
  2186.                                 break;
  2187.                         case asplus:
  2188.                                 op = en_asadd;
  2189.         
  2190. ascomm3:                                                getsym();
  2191.                                                                 tp2 = asnop(&ep2,asntyp);
  2192.                                 if( tp1->type == bt_pointer ) {
  2193.                                                                                 if (tp1->btp->size == 0)
  2194.                                                                                     generror(ERR_ZEROPTR,0,0);
  2195.                                         ep3 = makenode(en_icon,(char *)tp1->btp->size,0);
  2196.                                         ep2 = makenode(en_pmul,ep2,ep3);
  2197.                                                                                 tp2 = tp1;
  2198.                                         }
  2199.                                 goto ascomm2;
  2200.                         case asminus:
  2201.                                 op = en_assub;
  2202.                                 goto ascomm3;
  2203.                         case astimes:
  2204.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  2205.                                         op = en_asumul;
  2206.                                 else
  2207.                                         op =en_asmul;
  2208.                                 goto ascomm;
  2209.                         case asdivide:
  2210.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  2211.                                         op = en_asudiv;
  2212.                                 else
  2213.                                         op =en_asdiv;
  2214.                                 goto ascomm;
  2215.                         case asmodop:
  2216.                                 if( tp1->type == bt_unsigned ||tp1->type == bt_unsignedchar || tp1->type == bt_unsignedshort)
  2217.                                         op = en_asumod;
  2218.                                 else
  2219.                                         op =en_asmod;
  2220.                                 goto ascomm;
  2221.                         case aslshift:
  2222.                                                         if (tp1->type == bt_unsigned ||
  2223.                                                                 tp1->type == bt_unsignedchar ||
  2224.                                                                 tp1->type == bt_unsignedshort)
  2225.                                                             op = en_aslsh;
  2226.                                                         else
  2227.                               op = en_asalsh;
  2228.                                 goto ascomm;
  2229.                         case asrshift:
  2230.                                                         if (tp1->type == bt_unsigned ||
  2231.                                                                 tp1->type == bt_unsignedchar ||
  2232.                                                                 tp1->type == bt_unsignedshort)
  2233.                                                             op = en_asrsh;
  2234.                                                         else
  2235.                               op = en_asarsh;
  2236.                                 goto ascomm;
  2237.                         case asand:
  2238.                                 op = en_asand;
  2239.                                 goto ascomm;
  2240.                         case asor:
  2241.                                 op = en_asor;
  2242.                                 goto ascomm;
  2243.                         case asxor:
  2244.                                 op = en_asxor;
  2245.                                 goto ascomm;
  2246.                         default:
  2247.                                 goto asexit;
  2248.                         }
  2249.                 }
  2250. asexit: *node = ep1;
  2251.                 asntyp = oldastyp;
  2252.         return tp1;
  2253. }
  2254.  
  2255. TYP     *exprnc(ENODE **node)
  2256. /*
  2257.  *      evaluate an expression where the comma operator is not legal.
  2258.  * e.g. a function argument
  2259.  */
  2260. {       TYP     *tp;
  2261.         tp = asnop(node,0);
  2262.         if( tp == 0 )
  2263.                 *node = 0;
  2264.                 else if ((*node)->nodetype == en_fcallb || (*node)->nodetype == en_pfcallb) {
  2265.                         if ((*node)->nodetype == en_pfcallb) 
  2266.                             (*node) = makenode(en_pcallblock,dummyvar(tp->size,tp),(*node));
  2267.                       else
  2268.                             (*node) = makenode(en_callblock,dummyvar(tp->size,tp),(*node));
  2269.                 }
  2270.                 if (tp && tp->type == bt_void)
  2271.                     goodcode |= GF_ASSIGN;
  2272.         return tp;
  2273. }
  2274.  
  2275. TYP     *commaop(ENODE **node)
  2276. /*
  2277.  *      evaluate the comma operator. comma operators are kept as
  2278.  *      void nodes.
  2279.  */
  2280. {       TYP             *tp1;
  2281.         ENODE    *ep1, *ep2;
  2282.     int ocode;
  2283.         tp1 = asnop(&ep1,0);
  2284.         if( tp1 == 0 )
  2285.                 return 0;
  2286.         if( lastst == comma ) {
  2287.                                 ocode = goodcode | ~GF_ASSIGN;
  2288.                                 goodcode &= ~GF_ASSIGN;
  2289.                                 getsym();
  2290.                 tp1 = commaop(&ep2);
  2291.                                 goodcode &= ocode;
  2292.                 if( tp1 == 0 ) {
  2293.                         generror(ERR_IDEXPECT,0,0);
  2294.                         goto coexit;
  2295.                         }
  2296.                 ep1 = makenode(en_void,ep1,ep2);
  2297.                 }
  2298. coexit: *node = ep1;
  2299.         return tp1;
  2300. }
  2301.  
  2302. TYP     *expression(ENODE **node)
  2303. /*
  2304.  *      evaluate an expression where all operators are legal.
  2305.  */
  2306. {       TYP     *tp;
  2307.         tp = commaop(node);
  2308.         if( tp == 0 )
  2309.                 *node = 0;
  2310.                 else if ((*node)->nodetype == en_fcallb || (*node)->nodetype == en_pfcallb) {
  2311.                         if ((*node)->nodetype == en_pfcallb) 
  2312.                             (*node) = makenode(en_pcallblock,dummyvar(tp->size,tp),(*node));
  2313.                       else
  2314.                             (*node) = makenode(en_callblock,dummyvar(tp->size,tp),(*node));
  2315.                 }
  2316.                 if (tp && tp->type == bt_void)
  2317.                     goodcode |= GF_ASSIGN;
  2318.         return tp;
  2319. }